home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
SciAn
/
src
/
ScianSnap.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
14KB
|
703 lines
/*ScianSnap.c
Eric Pepke
14 January 1993
Routines for variable snapshots in SciAn
*/
#include "Scian.h"
#include "ScianTypes.h"
#include "ScianIDs.h"
#include "ScianLists.h"
#include "ScianArrays.h"
#include "ScianErrors.h"
#include "ScianSnap.h"
#include "ScianWindows.h"
#include "ScianObjWindows.h"
#include "ScianControls.h"
#include "ScianSymbols.h"
#include "ScianGarbageMan.h"
#include "ScianMethods.h"
#include "ScianDatabase.h"
#include "ScianDepend.h"
#include "ScianTextFiles.h"
#include "ScianScripts.h"
ObjPtr snapshotClass; /*Class for all snapshots*/
#ifdef PROTO
void AddSnapVar(ObjPtr object, NameTyp var)
#else
void AddSnapVar(object, var)
ObjPtr object;
NameTyp var;
#endif
/*Adds a snap var to object*/
{
ObjPtr snapVars;
snapVars = Get1Var(object, SNAPVARS);
if (!snapVars)
{
snapVars = NewList();
}
PostfixList(snapVars, NewSymbol(var));
SetVar(object, SNAPVARS, snapVars);
}
#ifdef PROTO
ObjPtr AssembleSnapVars(ObjPtr object)
#else
ObjPtr AssembleSnapVars(object)
ObjPtr object;
#endif
/*Assembles some snap vars from object, superclass first*/
{
if (object)
{
ObjPtr retVal;
ObjPtr curSnapVars;
ThingListPtr runner;
retVal = AssembleSnapVars(ClassOf(object));
curSnapVars = Get1Var(object, SNAPVARS);
if (curSnapVars && IsList(curSnapVars))
{
if (!retVal)
{
retVal = NewList();
}
for (runner = LISTOF(curSnapVars); runner; runner = runner -> next)
{
if (WhichListIndex(retVal, runner -> thing) < 0)
{
PostfixList(retVal, runner -> thing);
}
}
}
return retVal;
}
else
{
return NULLOBJ;
}
}
#ifdef PROTO
ObjPtr TakeSnapshot(ObjPtr object)
#else
ObjPtr TakeSnapshot(object)
ObjPtr object;
#endif
/*Takes a snapshot of object*/
{
ObjPtr list;
ObjPtr retVal;
/*Make the snap vars*/
list = AssembleSnapVars(object);
retVal = NewObject(snapshotClass, 0L);
SetVar(retVal, REPOBJ, object);
SetVar(retVal, SNAPVARS, list);
if (list)
{
ThingListPtr runner;
runner = LISTOF(list);
while (runner)
{
NameTyp id;
id = GetSymbolID(runner -> thing);
if (id)
{
MakeVar(object, id);
SetVar(retVal, id, GetVar(object, id));
}
runner = runner -> next;
}
}
SetVar(retVal, NAME, GetVar(object, NAME));
SetVar(retVal, REPCLASSID, GetVar(object, CLASSID));
return retVal;
}
#ifdef PROTO
ObjPtr TakeVarsSnapshot(ObjPtr object, ObjPtr list)
#else
ObjPtr TakeVarsSnapshot(object)
ObjPtr object;
#endif
/*Takes a snapshot of object, the variables in list.*/
{
ObjPtr retVal;
retVal = NewObject(snapshotClass, 0L);
SetVar(retVal, REPOBJ, object);
SetVar(retVal, SNAPVARS, list);
if (list)
{
ThingListPtr runner;
runner = LISTOF(list);
while (runner)
{
NameTyp id;
id = GetSymbolID(runner -> thing);
if (id)
{
MakeVar(object, id);
SetVar(retVal, id, GetVar(object, id));
}
runner = runner -> next;
}
}
SetVar(retVal, NAME, GetVar(object, NAME));
SetVar(retVal, REPCLASSID, GetVar(object, CLASSID));
return retVal;
}
#ifdef PROTO
ObjPtr TakeSingleVarSnapshot(ObjPtr object, NameTyp whichVar)
#else
ObjPtr TakeSingleVarSnapshot(object, whichVar)
ObjPtr object;
NameTyp whichVar;
#endif
/*Takes a snapshot of object*/
{
ObjPtr list;
ObjPtr retVal;
/*Make the snap vars*/
list = NewList();
PostfixList(list, NewSymbol(whichVar));
retVal = NewObject(snapshotClass, 0L);
SetVar(retVal, REPOBJ, object);
SetVar(retVal, SNAPVARS, list);
if (list)
{
ThingListPtr runner;
runner = LISTOF(list);
while (runner)
{
NameTyp id;
id = GetSymbolID(runner -> thing);
if (id)
{
MakeVar(object, id);
SetVar(retVal, id, GetVar(object, id));
}
runner = runner -> next;
}
}
SetVar(retVal, NAME, GetVar(object, NAME));
SetVar(retVal, REPCLASSID, GetVar(object, CLASSID));
return retVal;
}
#ifdef PROTO
Bool EqualSnapshots(ObjPtr snap1, ObjPtr snap2)
#else
Bool EqualSnapshots(snap1, snap2)
ObjPtr snap1, snap2;
#endif
/*Returns true iff the two snapshots are equal. BUGS--assumes that snapvars
are equal, so only use this on something like a track control where the
var group is constant*/
{
ObjPtr var1, var2;
ThingListPtr runner;
var1 = GetVar(snap1, REPOBJ);
var2 = GetVar(snap2, REPOBJ);
if (var1 != var2) return false;
var1 = GetVar(snap1, SNAPVARS);
if (var1)
{
for (runner = LISTOF(var1); runner; runner = runner -> next)
{
var1 = GetVar(snap1, GetSymbolID(runner -> thing));
var2 = GetVar(snap2, GetSymbolID(runner -> thing));
if (!Equal(var1, var2)) return false;
}
}
return true;
}
#ifdef PROTO
void PullSnapVars(ObjPtr newObject, ObjPtr oldObject)
#else
void TakeSnapshot(newObject, oldObject)
ObjPtr newObject, oldObject;
#endif
/*Transters the snap vars of newObject from corresponding values in oldObject*/
{
ObjPtr list;
ObjPtr retVal;
/*Make the snap vars*/
list = AssembleSnapVars(newObject);
if (list)
{
ThingListPtr runner;
runner = LISTOF(list);
while (runner)
{
NameTyp id;
id = GetSymbolID(runner -> thing);
if (id)
{
SetVar(newObject, id, GetVar(oldObject, id));
}
runner = runner -> next;
}
}
}
#ifdef PROTO
void ApplySnapshotTo(ObjPtr snapshot, ObjPtr object)
#else
void ApplySnapshotTp(snapshot, object)
ObjPtr snapshot;
ObjPtr object;
#endif
/*Applies snapshot to an object*/
{
ObjPtr list;
list = GetVar(snapshot, SNAPVARS);
if (list && object)
{
ThingListPtr runner;
ObjPtr value;
runner = LISTOF(list);
while (runner)
{
NameTyp id;
id = GetSymbolID(runner -> thing);
if (id)
{
if (id == VALUE)
{
value = GetVar(snapshot, VALUE);
SetValue(object, value);
}
else
{
SetVar(object, id, GetVar(snapshot, id));
}
}
runner = runner -> next;
}
ImInvalid(object);
}
}
#ifdef PROTO
void ApplySnapshot(ObjPtr snapshot)
#else
void ApplySnapshot(snapshot)
ObjPtr snapshot;
#endif
/*Applies snapshot to its object*/
{
ObjPtr object;
object = GetVar(snapshot, REPOBJ);
ApplySnapshotTo(snapshot, object);
}
#ifdef PROTO
ObjPtr InterpSimpleObjects(ObjPtr var1, ObjPtr var2, real weight)
#else
ObjPtr InterpSimpleObjects(var1, var2, weight)
ObjPtr var1, var2;
real weight;
#endif
/*Interpolates between two simple objects according to weight. 0 means
all var1, and 1 means all var2. If it can't interpolate, prints out
an error message and does a weighted choice.*/
{
if (IsInt(var1) && IsInt(var2))
{
/*Interpolation of integers*/
real r1, r2;
r1 = (real) GetInt(var1);
r2 = (real) GetInt(var2);
return NewInt((int) floor(r2 * weight + r1 * (1.0 - weight) + 0.5));
}
else if ((IsReal(var1) || IsInt(var1)) && (IsReal(var2) || IsInt(var2)))
{
/*Interpolation of real numbers*/
real r1, r2;
r1 = GetReal(var1);
r2 = GetReal(var2);
return NewReal(r2 * weight + r1 * (1.0 - weight));
}
else if (IsString(var1) && IsString(var2))
{
/*Interpolation of strings.*/
return (weight >= 0.5) ? var2 : var1;
}
else if (IsRealArray(var1) && IsRealArray(var2))
{
/*Interpolation of real arrays*/
long k;
long length;
real *el1, *el2, *el3;
ObjPtr retVal;
/*Make sure that the dimensions are the same*/
if (RANK(var1) != RANK(var2))
{
ReportError("InterpSimpleObjects", "Array rank mismatch");
return (weight >= 0.5) ? var2 : var1;
}
length = 1;
for (k = 0; k < RANK(var1); ++k)
{
if (DIMS(var1)[k] != DIMS(var2)[k])
{
ReportError("InterpSimpleObjects", "Array dimension mismatch");
return (weight >= 0.5) ? var2 : var1;
}
length *= DIMS(var1)[k];
}
el1 = ELEMENTS(var1);
el2 = ELEMENTS(var2);
retVal = NewArray(AT_REAL, RANK(var1), DIMS(var1));
if (!retVal)
{
return (weight >= 0.5) ? var2 : var1;
}
el3 = ELEMENTS(retVal);
for (k = 0; k < length; ++k)
{
if (el1[k] == missingData || el1[k] == plusInf || el1[k] == minusInf ||
el2[k] == missingData || el2[k] == plusInf || el2[k] == minusInf)
{
el3[k] = (weight >= 0.5) ? el2[k] : el1[k];
}
else
{
el3[k] = weight * el2[k] + (1.0 - weight) * el1[k];
}
}
return retVal;
}
else if (IsObject(var1) && IsObject(var2))
{
/*Just two objects*/
return (weight >= 0.5) ? var2 : var1;
}
else
{
char errmes[256];
sprintf(errmes, "Cannot interpolate between values %x and %x\n", var1, var2);
ReportError("InterpSimpleObjects", errmes);
return (weight >= 0.5) ? var2 : var1;
}
}
#ifdef PROTO
ObjPtr InterpSnapshots(ObjPtr snap1, ObjPtr snap2, real weight)
#else
ObjPtr InterpSnapshots(snap1, snap2, weight)
ObjPtr snap1, snap2;
real weight;
#endif
/*Returns a weighted interpolation of two snapshots. Assumes that they have
the same variables.*/
{
ObjPtr variables;
ObjPtr var1, var2;
ObjPtr retVal;
ThingListPtr runner;
retVal = NewObject(snapshotClass, 0L);
/*Make the snap vars*/
variables = GetListVar("InterpSnapshots", snap1, SNAPVARS);
if (!variables) return ObjFalse;
SetVar(retVal, SNAPVARS, CopyList(variables));
SetVar(retVal, REPOBJ, GetVar(snap1, REPOBJ));
SetVar(retVal, NAME, GetVar(snap1, NAME));
SetVar(retVal, REPCLASSID, GetVar(snap1, CLASSID));
/*Interpolate the variables*/
runner = LISTOF(variables);
while (runner)
{
NameTyp id;
id = GetSymbolID(runner -> thing);
var1 = GetVar(snap1, id);
var2 = GetVar(snap2, id);
SetVar(retVal, id, InterpSimpleObjects(var1, var2, weight));
runner = runner -> next;
}
return retVal;
}
#ifdef PROTO
void LogSnapshot(ObjPtr object)
#else
void LogSnapshot(object)
ObjPtr object;
#endif
/*Logs a snapshot of object*/
{
ObjPtr list;
ObjPtr retVal;
Bool needsWindow = false;
needsWindow = MakeObjectName(tempStr, object);
if (needsWindow)
{
Log("begin snapshot ");
Log(tempStr);
Log("\n");
}
else
{
LogNoWindow("begin snapshot ");
LogNoWindow(tempStr);
LogNoWindow("\n");
}
/*Make the snap vars*/
list = AssembleSnapVars(object);
if (list)
{
ThingListPtr runner;
char cmd[256];
char *s;
runner = LISTOF(list);
while (runner)
{
NameTyp id;
ObjPtr value;
id = GetSymbolID(runner -> thing);
if (id)
{
value = GetVar(object, id);
if (IsInt(value))
{
sprintf(cmd, " set variable %s (int) ", GetInternalString(id));
}
else
{
sprintf(cmd, " set variable %s ", GetInternalString(id));
}
s = &(cmd[0]);
while (*s) ++s;
PrintScriptObject(s, value);
while (*s) ++s;
*s++ = '\n';
*s = 0;
if (needsWindow)
{
Log(cmd);
}
else
{
LogNoWindow(cmd);
}
}
runner = runner -> next;
}
}
if (needsWindow)
{
Log("end snapshot\n");
}
else
{
LogNoWindow("end snapshot\n");
}
}
#ifdef PROTO
void SubsumeObjIntoDatabase(ObjPtr object)
#else
void SubsumeObjIntoDatabase(object)
ObjPtr object;
#endif
/*Subsumes an object into the database. This means---
1) Looks for an object with the same name and CLASS_ID
2) If found,
Replaces the object in the database with this object, but takes a
snapshot of the old object from the new object's snapvars and
applies it to the new object.
3) If not found, just adds this object to the database.
*/
{
ObjPtr keyList;
ObjPtr resultList;
keyList = NewList();
PostfixList(keyList, NewSymbol(NAME));
MakeVar(object, NAME);
PostfixList(keyList, GetVar(object, NAME));
PostfixList(keyList, NewSymbol(CLASSID));
MakeVar(object, CLASSID);
PostfixList(keyList, GetVar(object, CLASSID));
if (resultList = SearchDatabase(keyList))
{
if (LISTOF(resultList))
{
PullSnapVars(object, LISTOF(resultList) -> thing);
DeleteObjFromDatabase(LISTOF(resultList) -> thing);
}
}
AddObjToDatabase(object);
}
#ifdef PROTO
void ApplySavedSettings(ObjPtr object)
#else
void ApplySavedSettings(object)
ObjPtr object;
#endif
/*Applies the saved settings to object*/
{
ObjPtr directory;
directory = GetSettingsDirectory();
ReadObjectControls(object, directory, false);
}
#ifdef PROTO
ObjPtr GetSettingsDirectory(void)
#else
ObjPtr GetSettingsDirectory()
#endif
/*Returns a string of the settings directory, which by default is
~/scianSettings. Creates the directory if need be*/
{
char dirName[256];
struct stat buf;
int notThere;
sprintf(dirName, "%s/%s", getenv("HOME"), ".scianSettings");
notThere = stat(dirName, &buf);
if (notThere)
{
FILE *outFile;
/*Have to create it*/
if (mkdir(dirName, S_IREAD | S_IWRITE | S_IEXEC))
{
/*Failed to create*/
ReportError("GetSettingsDirectory", "Cannot create directory");
return NULLOBJ;
}
notThere = stat(dirName, &buf);
if (notThere)
{
/*Still not there, return null*/
ReportError("GetSettingsDirectory", "Tried create directory, but it's not there");
return NULLOBJ;
}
/*Put in a README*/
strcpy(tempStr, dirName);
strcat(tempStr, "/README");
outFile = fopen(tempStr, "w");
if (!outFile)
{
ReportError("GetSettingsDirectory", "Cannot create files in directory");
return NULLOBJ;
}
fprintf(outFile, "This directory is used to save settings from within SciAn.\n");
fclose(outFile);
}
/*Directory exists, see if it's OK*/
if ((buf.st_mode & S_IFMT) == S_IFDIR)
{
/*It's OK*/
return NewString(dirName);
}
ReportError("GetSettingsDirectory", "Problem using settings directory");
return NULLOBJ;
}
ObjPtr SaveSnapshotControls(object)
ObjPtr object;
/*Saves an object's controls from a snapshot*/
{
ObjPtr directory;
directory = GetSettingsDirectory();
SaveObjectControls(object, directory);
return ObjTrue;
}
ObjPtr LogSnapshotControls(object)
ObjPtr object;
/*Logs all the controls for an object*/
{
LogSnapshot(object);
return ObjTrue;
}
#ifdef PROTO
void InitSnapshots(void)
#else
void InitSnapshots()
#endif
/*Initializes snapshot system*/
{
snapshotClass = NewObject(NULLOBJ, 0L);
AddToReferenceList(snapshotClass);
SetVar(snapshotClass, CLASSID, NewInt(CLASS_SNAPSHOT));
classClasses[CLASS_SNAPSHOT] = snapshotClass;
}
#ifdef PROTO
void KillSnapshots(void)
#else
void KillSnapshots()
#endif
/*Kills the snapshot system*/
{
RemoveFromReferenceList(snapshotClass);
}